#include "../common/etcd.hpp"
#include "../common/channel.hpp"
#include "main.pb.h"
#include <gflags/gflags.h>
// 这是etcd当中监听的那个客户端，也是brpc的客户端
DEFINE_bool(run_mode, false, "程序运行模式:true为发布模式,false为调试模式");
DEFINE_string(log_file, "", "发布模式中,用于存放日志的文件路径");
DEFINE_int32(log_level, 0, "发布模式中,日志输出等级");
DEFINE_string(etcd_host, "http://127.0.0.1:2379", "服务注册中心地址");
DEFINE_string(base_service, "/service", "服务监控根目录");
DEFINE_string(call_service, "/service/echo", "调取的服务");
void online(const std::string &service_name, const std::string &host)
{
    LOG_DEBUG("上线服务：{}，地址：{}", service_name, host);
}
void offline(const std::string &service_name, const std::string &host)
{
    LOG_DEBUG("下线服务：{}，地址：{}", service_name, host);
}
int main(int argc, char *argv[])
{
    google::ParseCommandLineFlags(&argc, &argv, true);
    init_logger(FLAGS_run_mode, FLAGS_log_file, FLAGS_log_level);

    // 先构造信道管理对象，
    auto sm = std::make_shared<ServiceManager>();
    sm->declared(FLAGS_call_service);
    auto put_cb = std::bind(&ServiceManager::onServiceOnline, sm.get(), std::placeholders::_1, std::placeholders::_2);
    auto del_cb = std::bind(&ServiceManager::onServiceOffline, sm.get(), std::placeholders::_1, std::placeholders::_2); // sm.get()返回sm的裸指针，也是这个函数的this指针
    // 再构建服务发现对象，
    Discovery::ptr dclient = std::make_shared<Discovery>(FLAGS_etcd_host, FLAGS_base_service, put_cb, del_cb);

    while (1)
    {
        // 通过rpc信道管理对象，获取提供echo服务的信道
        auto channel = sm->choose(FLAGS_call_service);
        if (!channel)
        {
            //LOG_ERROR("没有找到{}服务的节点", FLAGS_call_service);
            std::this_thread::sleep_for(std::chrono::seconds(1));
            continue;
        }
        // 发起echorpc请求
        example::EchoService_Stub stub(channel.get());
        example::EchoRequest request;
        request.set_message("hello");
        brpc::Controller *cntl = new brpc::Controller(); // 上下文管理类，目前也就是判断rpc请求是否ok
        example::EchoResponse *response = new example::EchoResponse();
        stub.Echo(cntl, &request, response, nullptr); // 异步才传第四个参数，同步传null

        if (cntl->Failed())
        {
            std::cout << "rpc调用失败:" << cntl->ErrorText() << std::endl;
            delete cntl;
            delete response;
            std::this_thread::sleep_for(std::chrono::seconds(1));
            continue;
        }
        std::cout << "收到响应:" << response->message() << std::endl;
        break;
    }
}